package com.chinacoal.microservice.excption;

import com.auth0.jwt.exceptions.JWTDecodeException;
import com.chinacoal.microservice.util.CodeMsg;
import com.chinacoal.microservice.util.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;

/**
 * @author zhuliang
 * @version V1.0
 * @Description: 全局异常处理类
 * @date 2020-11-06 14：10
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandlers {

    @ExceptionHandler(value = CodeMsg.class)
    @ResponseBody
    public Result<String> errorHandler(HttpServletRequest req, CodeMsg e) {

        log.error(e.toString() + "");

        return Result.error(e);
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result<String> defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {

        log.error("", e);

        if (e instanceof NoHandlerFoundException) {

            return Result.error(CodeMsg.NOT_FOUND);

        } else if (e instanceof JWTDecodeException) {

            return Result.error(CodeMsg.TOKEN_ABNORMAL_FORMAT);

        } else if(e instanceof HttpRequestMethodNotSupportedException) {

            return Result.error(CodeMsg.METHOD_NOT_SUPPORTED);

        }else if(e instanceof IllegalArgumentException || e instanceof NumberFormatException || e instanceof MethodArgumentTypeMismatchException
                || e instanceof HttpMessageNotReadableException || e instanceof MissingServletRequestParameterException){

            return Result.error(CodeMsg.IllegalArgumentException);

        }else if(e instanceof MethodArgumentNotValidException) {

            BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();

            if(bindingResult.hasFieldErrors()) {
                String defaultMessage = bindingResult.getFieldError().getDefaultMessage();
                return Result.error(CodeMsg.BIND_ERROR.fillArgs(defaultMessage));
            }

            return Result.error(CodeMsg.BIND_ERROR);

        }else if(e instanceof MissingServletRequestParameterException){

            String paramName = ((MissingServletRequestParameterException) e).getParameterName();

            return Result.error(CodeMsg.BIND_ERROR.fillArgs(paramName));

        }else if(e instanceof DuplicateKeyException){

            return Result.error(CodeMsg.SQL_ERROR);

        }else if (e instanceof NullPointerException) {

            return Result.error(CodeMsg.NULL_ABNORMAL);

        } else{

            return Result.error(CodeMsg.SERVER_ERROR.fillArgs(e.getMessage()));

        }
    }
}
